package deadlock

import 	(
	"fmt"
	"dumpwave"
	)


type DECO struct{
	CP0_COMMAND, CP0_BDS uint32
}

type DERE struct{
	RF_COMMAND, RS, RT, RD uint32 // Em caso de instruções do tipo Load/Store/Branch RS=BASE RD=OFFSET
}

type DEDM struct{
	DMUX_COMMAND, DMUX_UNIT uint32
}

type DEMU struct{
	MUX_COMMAND, MUX_UNIT uint32
}

type ALMU struct{
	EXEC_TO_REG		int32
	CANCELLED		bool
}

type MURE struct{
	WRITE		int32
	CANCELLED	bool
}

type REDM struct{
	BUS1, BUS2 int32
}

type DMAL struct{
	BUS1, BUS2 int32
}

type DEPC struct{
	PC_COMMAND, PC_IMMEDIATE, PC_OFFSET, PC_BUFFERS uint32
}

type DEAL struct{
	CMD, IMMEDIATE uint32
}

func Yam(
	instruction_address chan uint32,
	instruction chan uint32,
	ls_addr     chan uint32,
	ls_rw       chan bool,
	ls_data_in  chan int32,
	ls_data_out chan int32) {
	
	decodeMux := make(chan DEMU)
	aluMux := make(chan ALMU)
	//decodeAlu := make(chan int32)
	decodeAlu := make(chan DEAL)
	decodeRegister := make(chan DERE)
	muxRegister := make(chan MURE)
	exception := make(chan int32)
	decodeCop0 := make(chan DECO)
	registerDmux := make(chan REDM)
	dmuxAlu := make(chan DMAL)
	decodeDmux := make(chan DEDM)
	decodePC := make(chan DEPC)
	aluPc := make(chan uint32)
	

	////////////////////////////////////////////////////////
	//cria/abre o arquivo em modo de escrita
	//disparo do relógio para sincronia dos values dumps
	///////////////////////////////////////////////////////
	dumpwave.IniciaWave(datainiciatial)
	///////////////////////////////////////////////////////

	fmt.Println("[YAM] Iniciando PC")
	go pc(instruction_address, decodePC,aluPc)
	
	fmt.Println("[YAM] Iniciando decode")
	go decode(instruction, decodeAlu, decodeCop0, decodeRegister, decodeDmux, decodeMux, decodePC)
	
	fmt.Println("[YAM] Iniciando mux")
	go mux(decodeMux, aluMux, muxRegister)
	
	fmt.Println("[YAM] Iniciando dmux")
	go dmux(decodeDmux, registerDmux, dmuxAlu)
	
	fmt.Println("[YAM] Iniciando register")
	go register(decodeRegister, muxRegister, registerDmux)
	
	fmt.Println("[YAM] Iniciando ALU")
	go alu(decodeAlu, dmuxAlu, aluMux, exception, ls_addr, ls_rw, ls_data_in, ls_data_out,aluPc)
	
	fmt.Println("[YAM] Iniciando COP0")
	go cop0(exception, decodeCop0)
}